from django.db import models
from django.utils.translation import gettext_lazy as _

from identify.models import User


class State(models.IntegerChoices):
    DRAFT = 0, _("Draft")
    PUBLISHED = 1, _("Published")
    PRIVATE = 2, _("Private")
    ARCHIVED = 3, _("Archived")


class Notebook(models.Model):
    title = models.CharField(max_length=50, verbose_name=_("Title"))
    content = models.TextField(verbose_name=_("Content"))
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=_("Created Time"))
    updated_time = models.DateTimeField(auto_now=True, verbose_name=_("Updated Time"))

    # 字段可提供 choices 参数，该参数接受一个二值元组的 sequence、mapping、枚举或可调用对象（不接受参数且返回上述三种类型之一）
    # https://docs.djangoproject.com/zh-hans/5.2/topics/db/models/#field-options
    # shell 中可以使用 notebook.get_state_display() 来获取 state 字段的可读名称
    state = models.IntegerField(choices=State.choices, default=State.DRAFT, verbose_name=_("State"))

    # 与用户定义一对多关系，on_delete=models.CASCADE 表示级联删除，UPDATE 不支持显式指定，因为更新不常用
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name=_("User"))

    class Meta:
        verbose_name = _("Notebook")
        verbose_name_plural = _("Notebooks")

    def __repr__(self) -> str:
        return f"<Notebook object: {self.title}>"

    def __str__(self):
        return self.title


class Category(models.Model):
    name = models.CharField(max_length=50, verbose_name=_("Category Name"))
    slug = models.SlugField(max_length=50, unique=True, verbose_name=_("Slug"))
    description = models.TextField(blank=True, null=True, verbose_name=_("Description"))
    notebooks = models.ManyToManyField(Notebook, through="Relationship", verbose_name=_("Notebooks"))

    class Meta:
        verbose_name = _("Category")
        verbose_name_plural = _("Categories")

    def __str__(self):
        return self.name


class Relationship(models.Model):
    notebook = models.ForeignKey(Notebook, on_delete=models.CASCADE, verbose_name=_("Notebook"))
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=_("Category"))

    class Meta:
        verbose_name = _("Relationship")
        verbose_name_plural = _("Relationships")
        constraints = [models.UniqueConstraint(fields=["notebook", "category"], name="unique_notebook_category")]

    def __str__(self):
        return f"{self.notebook.title} - {self.category.name}"
